package com.logicfishsoftware.owlet.jena;


import com.hp.hpl.jena.query.Dataset;
import com.logicfishsoftware.owlet.app.Application;
import com.logicfishsoftware.owlet.app.ApplicationException;
import com.logicfishsoftware.owlet.app.Operator;
import com.logicfishsoftware.owlet.app.runtime.RuntimeApplication;

/**
 * Hello world!
 *
 */
public abstract class JenaDatasetApp<T extends JenaDatasetApp<T,U>.JenaDatasetAtom,U extends JenaDatasetApp<T,U>.JenaDatasetContext>
extends RuntimeApplication<T,U>
implements Application<JenaDatasetOperator<U>>
{
	class JenaDatasetContext
	extends RuntimeApplication<T,U>.ApplicationContext {

		private T atomic;

		/**
		 * @param atomic
		 */
		protected JenaDatasetContext(T atomic) {
			this.atomic = atomic;
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.runtime.RuntimeApplication.ApplicationContext#dispose()
		 */
		protected void dispose() throws ApplicationException {
			atomic.dispose();
		}

		/**
		 * @return
		 */
		public Dataset getDataset() {
			return atomic.getDataset();
		}

	}
	class JenaDatasetAtom
	extends RuntimeApplication<T, U>.ApplicationAtom 
	{
		private JenaDatasetOperator<? super U> delegate;
		private Dataset dataset;

		/**
		 * @param delegate
		 */
		protected JenaDatasetAtom(JenaDatasetOperator<? super U> delegate) {
			this.delegate = delegate;
		}

		/**
		 * @param proceed
		 */
		protected JenaDatasetAtom(Operator<? super U> proceed) {
			this((JenaDatasetOperator<? super U>)proceed);
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom#application(com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationContext)
		 */
		@Override
		protected boolean application(U context) throws Exception {
			return delegate.application(context);
		}

		/**
		 * @return
		 */
		protected Dataset getDataset() {
			if(this.dataset == null)
				this.dataset = delegate.createDataset();
			return this.dataset;
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom#proceed()
		 */
		@Override
		protected T proceed() throws ApplicationException {
			Operator<? super U> proceed = delegate.proceed();
			delegate = null;
			if(proceed!=null)
				return createAtom(proceed);
			return null;
		}
		
		protected void dispose() throws ApplicationException {
			if(dataset != null)
				dataset.close();
			dataset = null;
		}
		
		
	}
	/* (non-Javadoc)
	 * @see com.logicfishsoftware.owlet.app.Application#apply(java.lang.Object)
	 */
	public boolean enter(JenaDatasetOperator<U> delegate) throws ApplicationException {
		return enter(createAtom(delegate));
	}
	/* (non-Javadoc)
	 * @see com.logicfishsoftware.owlet.app.ApplicationRuntime#createFrame(com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom)
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected U createAppContext(T atomic) {
		return (U) new JenaDatasetContext(atomic);
	}
	@SuppressWarnings("unchecked")
	protected T createAtom(Operator<? super U> delegate) {
		return (T) new JenaDatasetAtom(delegate);
	}
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}
